package com.heima.lock.lock;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
public class LockController {;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 基于redis实现分布式锁
     * @return
     */
    @GetMapping("stock")
    public String Lock() {
        //1、成功插入数据 线程id 以及失效时间 就是获得锁
        Boolean isLock = redisTemplate.opsForValue().setIfAbsent("lock", String.valueOf(Thread.currentThread().getId()), 30, TimeUnit.SECONDS);
        //2、如果获得锁，执行业务
        if (isLock) {
            //执行业务
            int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock").toString());
            if (stock > 0) {
                stock--;
                redisTemplate.opsForValue().set("stock", String.valueOf(stock));
                System.out.println("扣减库存成功，剩余库存为：" + stock);
            }else {
                System.out.println("库存不足");
            }
            //释放锁 但是要判断 锁是否存在以及是否是自己的
            if (redisTemplate.opsForValue().get("lock") != null && redisTemplate.opsForValue().get("lock").toString().equals(String.valueOf(Thread.currentThread().getId()))) {
                redisTemplate.delete("lock");

            }
        } else {
            System.out.println("么有抢到分布式锁");
        }
        return "ok";
    }

    @GetMapping("stock2")
    public String stock2() {
        //1、获得锁对象
        RLock lock = redissonClient.getLock("lock");
        //2、加锁 默认是看门狗
        lock.lock(); //阻塞锁  默认watch-dog 锁失效时间：30秒。底层基于观察者模式实现锁的自动续期  非阻塞锁 trylock 有返回值
        //3、”消费“
        try {
            Integer stock = Integer.valueOf(redisTemplate.opsForValue().get("stock").toString());
            if (stock > 0) {
                stock--;
                System.out.println("库存减一，库存还剩下：" + stock);
                redisTemplate.opsForValue().set("stock",String.valueOf(stock));
            }else {
                System.out.println("库存不足");
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }finally {
            //放锁
            lock.unlock();
        }

        System.out.println("没有抢到分布式锁");
        return "ok";
    }
}
